package com.apobates.jforum2.troll.actionlog.controller;

import com.apobates.jforum2.troll.actionlog.biz.BoardActionCollectionService;
import com.apobates.jforum2.troll.actionlog.biz.TopicActionCollectionService;
import com.apobates.jforum2.troll.actionlog.entity.BoardActionCollection;
import com.apobates.jforum2.troll.actionlog.entity.TopicActionCollection;
import com.apobates.jforum2.troll.actionlog.mapper.BoardActionVoMapperEntity;
import com.apobates.jforum2.troll.actionlog.mapper.ThreadsActionVoMapperEntity;
import com.apobates.jforum2.troll.actionlog.stub.vo.BoardActionVo;
import com.apobates.jforum2.troll.actionlog.stub.vo.MemberModelVo;
import com.apobates.jforum2.troll.actionlog.stub.vo.ThreadsStatsCollectVo;
import com.apobates.jforum2.troll.actionlog.stub.vo.TopicActionVo;
import com.apobates.jforum2.troll.regular.ForumActionEnum;
import com.apobates.jforum2.troll.utils.core.Commons;
import com.apobates.jforum2.troll.utils.core.EntityPageResult;
import com.apobates.jforum2.troll.utils.core.ResponseResult;
import com.apobates.jforum2.troll.utils.persistence.Page;
import com.apobates.jforum2.troll.utils.persistence.PageRequest;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;

/**
 * 操作日志Api
 *
 * @author xiaofanku
 * @since 20201114
 */
@RestController
@RequestMapping("/logs")
public class ActionLogController {
    @Autowired
    private TopicActionCollectionService topicActionCollectionService;
    @Autowired
    private BoardActionCollectionService boardActionCollectionService;
    private final static Logger logger = LoggerFactory.getLogger(ActionLogController.class);

    //业务操作中脱离出来的业务子步聚
    @GetMapping("/topic/liked")
    public boolean isLikedTopic(@RequestParam("topic")long topicId, @RequestParam("member")long memberId){
        return topicActionCollectionService.isLikedTopic(topicId, memberId).orElse(false);
    }
    @GetMapping("/topic/favorited")
    public boolean isFavoritedTopic(@RequestParam("topic")long topicId, @RequestParam("member")long memberId){
        return topicActionCollectionService.isFavoritedTopic(topicId, memberId).orElse(false);
    }
    @GetMapping("/topic/action/member")
    public long getActionTopic(@RequestParam("topic")long topicId, @RequestParam("member")long memberId, @RequestParam("action")ForumActionEnum action){
        return topicActionCollectionService.countMemberTopicAction(memberId, topicId, action);
    }
    //从话题点赞/取消点赞中脱离出来 | 从话题收藏/取消收藏中脱离出来
    //为下次取消点赞/点赞清路      | 为下次取消收藏/收藏清路
    @PostMapping(value="/topic/action/delete", consumes="application/x-www-form-urlencoded")
    public boolean removeActionTopic(@RequestParam("topic")long topicId, @RequestParam("member")long memberId, @RequestParam("action")ForumActionEnum action){
        return topicActionCollectionService.remove(topicId, memberId, action);
    }
    
    @GetMapping("/board/favorited")
    public boolean isFavoritedBoard(@RequestParam("board")long boardId, @RequestParam("member")long memberId){
        return boardActionCollectionService.isFavoritedBoard(boardId, memberId).orElse(false);
    }
    @GetMapping("/board/action/member")
    public long getActionBoard(@RequestParam("board")long boardId, @RequestParam("member")long memberId, @RequestParam("action")ForumActionEnum action){
        return boardActionCollectionService.countMemberBoardAction(memberId, boardId, action);
    }
    //从版块收藏/取消收藏中脱离出来
    //为下次取消收藏/收藏清路
    @PostMapping(value="/board/action/delete", consumes="application/x-www-form-urlencoded")
    public boolean removeActionBoard(@RequestParam("board")long boardId, @RequestParam("member")long memberId, @RequestParam("action")ForumActionEnum action){
        return boardActionCollectionService.remove(boardId, memberId, action);
    }
    //-----------------------------------MemberController
    //9:会员话题操作统计信息
    @GetMapping("/{member}/topic/stats")
    public ResponseEntity<ThreadsStatsCollectVo> getTopicActionStats(@PathVariable("member") long memberId){
        ThreadsStatsCollectVo tsc = getStats(memberId);
        //
        ResponseResult<ThreadsStatsCollectVo> rr = ResponseResult.Helper.ofEntity(tsc);
        return ResponseEntity.status(rr.getCode()).contentType(MediaType.APPLICATION_JSON).body(rr.getEntity());
    }
    //11:会员操作统计
    @GetMapping("/{id}/topic/action/collect")
    public Map<ForumActionEnum, Long> getTopicActionCollect(@PathVariable("id") long memberId){
        return topicActionCollectionService.statsMemberAllAction(memberId);
    }
    //20:社区标兵
    @GetMapping("/model/stats")
    public List<MemberModelVo> getBrandMemberModel(@RequestParam(value="size", required=false, defaultValue="10") int showSize){
        Map<Long, Map<String, Long>> rs = topicActionCollectionService.orderMemberTopices(showSize);
        Function<Map.Entry<Long, Map<String, Long>>, MemberModelVo> coverMapper = entry->{
            long mid = entry.getKey();
            return entry.getValue().entrySet().stream().map(tmp->new MemberModelVo(mid, tmp.getValue(), tmp.getKey())).findFirst().get();
        };
        Stream<MemberModelVo> data = rs.entrySet().stream().map(coverMapper);
        return data.sorted(Comparator.comparing(MemberModelVo::getValue).reversed()).collect(Collectors.toList());
    }
    //24:会员的操作记录|需要前端api整合话题+回复
    @GetMapping("/{id}/topic/history/{page}/{number}")
    public EntityPageResult<TopicActionVo> getMemberActionHistory(@PathVariable("id") long memberId, @PathVariable("page") int page, @PathVariable("number") int pageSize){
        Page<TopicActionCollection> rs = topicActionCollectionService.getByMember(memberId, new PageRequest(page, pageSize));
        //
        ResponseResult<EntityPageResult<TopicActionVo>> rr = ResponseResult.PageResultBuilder.<TopicActionVo,TopicActionCollection>getInstance(page, pageSize)
                .from(rs.getTotalElements(), rs.getResult())
                .build(ThreadsActionVoMapperEntity.mapper());
        return rr.getData();
    }
    //25:会员收藏的话题|需要前端api整合话题+回复
    @GetMapping("/{id}/topic/favorite/{page}/{number}")
    public EntityPageResult<TopicActionVo> getMemberFavoriteTopic(@PathVariable("id") long memberId, @PathVariable("page") int page, @PathVariable("number") int pageSize){
        Page<TopicActionCollection> rs = topicActionCollectionService.getAllByMemberAction(memberId, ForumActionEnum.TOPIC_FAVORITE, new PageRequest(page, pageSize));
        //
        ResponseResult<EntityPageResult<TopicActionVo>> rr = ResponseResult.PageResultBuilder.<TopicActionVo,TopicActionCollection>getInstance(page, pageSize)
                .from(rs.getTotalElements(), rs.getResult())
                .build(ThreadsActionVoMapperEntity.mapper());
        return rr.getData();
    }
    //26:会员点赞的话题|需要前端api整合话题+回复
    @GetMapping("/{id}/topic/like/{page}/{number}")
    public EntityPageResult<TopicActionVo> getMemberLickTopic(@PathVariable("id") long memberId, @PathVariable("page") int page, @PathVariable("number") int pageSize){
        Page<TopicActionCollection> rs = topicActionCollectionService.getAllByMemberAction(memberId, ForumActionEnum.TOPIC_LIKED, new PageRequest(page, pageSize));
        //
        ResponseResult<EntityPageResult<TopicActionVo>> rr = ResponseResult.PageResultBuilder.<TopicActionVo,TopicActionCollection>getInstance(page, pageSize)
                .from(rs.getTotalElements(), rs.getResult())
                .build(ThreadsActionVoMapperEntity.mapper());
        return rr.getData();
    }
    //-----------------------------------BoardController
    //13:查看指定会员的版块收藏操作
    @GetMapping("/{id}/board/favorited")
    public List<BoardActionVo> getMemberFavoriteBoard(@PathVariable("id")long member, @RequestParam(value="size", required=false, defaultValue="10") int showSize){
        Stream<BoardActionCollection> rs = boardActionCollectionService.getMemberFavoriteBoard(member, showSize);
        return rs.map(BoardActionVoMapperEntity.mapper()).collect(Collectors.toList());
    }
    //15:分页查看指定会员收藏的版块
    @GetMapping("/{id}/board/favorited/{page}/{number}")
    public EntityPageResult<BoardActionVo> getMemberFavoriteBoard(@PathVariable("id") long memberId, @PathVariable("page") int page, @PathVariable("number") int pageSize){
        Page<BoardActionCollection> rs = boardActionCollectionService.getFavoritesForMember(memberId, new PageRequest(page, pageSize));
        //
        ResponseResult<EntityPageResult<BoardActionVo>> rr = ResponseResult.PageResultBuilder.<BoardActionVo,BoardActionCollection>getInstance(page, pageSize)
                .from(rs.getTotalElements(), rs.getResult())
                .build(BoardActionVoMapperEntity.mapper());
        return rr.getData();
    }

    private ThreadsStatsCollectVo getStats(long memberId) {
        ThreadsStatsCollectVo tscb = new ThreadsStatsCollectVo();
        Map<ForumActionEnum, Long> statsActions = topicActionCollectionService.statsMemberAction(memberId, List.of(ForumActionEnum.TOPIC_PUBLISH, ForumActionEnum.POSTS_REPLY, ForumActionEnum.TOPIC_LIKED, ForumActionEnum.TOPIC_FAVORITE));
        try {
            Long ts = statsActions.get(ForumActionEnum.TOPIC_PUBLISH);
            tscb.setThreads(Commons.optionalOrZero(ts));
        } catch (Exception e) {}
        try {
            Long rs = statsActions.get(ForumActionEnum.POSTS_REPLY);
            tscb.setReplies(Commons.optionalOrZero(rs));
        } catch (Exception e) {}
        //
        try {
            Long tls = statsActions.get(ForumActionEnum.TOPIC_LIKED);
            tscb.setThreadsLikes(Commons.optionalOrZero(tls));
        } catch (Exception e) {}
        try {
            Long fls = statsActions.get(ForumActionEnum.TOPIC_FAVORITE);
            tscb.setThreadsFavorites(Commons.optionalOrZero(fls));
        } catch (Exception e) {}
        return tscb;
    }
}